import ATransfer from '../transfer';
import CTable from '../c-table/CustomTable';
import { uniqBy } from '../_util/common';
import PropTypes from '../_util/vue-types';
import cloneDeep from 'lodash/cloneDeep';

let pagination = {
  current: 1,
  pageSize: 10,
};
export default {
  name: 'CTransferTable',
  props: {
    disabled: PropTypes.bool.def(false),
    titles: PropTypes.array.def(['left', 'right']),
    leftData: PropTypes.array.isRequired,
    // 左侧过滤规则，仅当左侧没有后台分页时使用
    leftFilter: PropTypes.object,
    rightData: PropTypes.array.isRequired,
    // 右侧过滤规则
    rightFilter: PropTypes.object,
    fieldMap: PropTypes.object.def({
      key: 'id',
      title: 'name',
    }),
    tableColumn: PropTypes.array,
    leftTableColumn: PropTypes.array,
    rightTableColumn: PropTypes.array,

    listStyle: PropTypes.object.def({
      //配合flex一起使用
      width: '40%',
      height: 'auto',
      maxHeight: '600px',
    }),
  },
  data() {
    return {
      leftSource: [],
      rightSource: [],
      selectedKeys: [],
      targetKeys: [],
      leftPagination: { ...pagination },
      rightPagination: { ...pagination },
    };
  },
  computed: {
    totalDataSource() {
      return uniqBy([...this.leftSource, ...this.rightSource], 'key');
    },
  },
  watch: {
    leftData: {
      handler(val) {
        this.leftSource = val.reduce((lastVal, item) => {
          let currKey = String(item[this.fieldMap.key]);
          //右侧不变，左侧数据发生变化的场景，比如：变更商务关联的商户
          if (!this.targetKeys.includes(currKey)) {
            lastVal.push({
              ...item,
              key: currKey,
              title: item[this.fieldMap.title],
            });
          }
          return lastVal;
        }, []);
      },
      immediate: true,
    },
    rightData: {
      handler(val) {
        this.rightSource = val.map(item => {
          return {
            ...item,
            key: String(item[this.fieldMap.key]),
            title: item[this.fieldMap.title],
          };
        });
        this.targetKeys = this.rightSource.map(item => item.key);
      },
      immediate: true,
    },
  },
  methods: {
    //供外部调用
    disabledRightSource() {
      this.rightSource.forEach(item => {
        item.disabled = true;
      });
    },
    //表格数据筛选
    localFilter(data = [], filters = {}) {
      return data.filter(item => {
        return Object.keys(filters).every(key => {
          let itemKey = String(item[key] || '');
          let filtersKey = filters[key] || '';
          if (Array.isArray(filtersKey)) {
            return filtersKey.length ? filtersKey.includes(itemKey) : true;
          }
          return itemKey.includes(filtersKey);
        });
      });
    },
    handleBtnChange(nextTargetKeys, direction, moveKeys) {
      this.targetKeys = nextTargetKeys;
      this.$emit('dataChanged', moveKeys);

      let leftSource = [];
      let rightSource = [];

      this.totalDataSource.forEach(item => {
        if (nextTargetKeys.includes(item.key)) {
          if (moveKeys.includes(item.key)) {
            rightSource.unshift(item);
          } else {
            rightSource.push(item);
          }
        } else {
          if (moveKeys.includes(item.key)) {
            leftSource.unshift(item);
          } else {
            leftSource.push(item);
          }
        }
      });

      this.leftSource = leftSource;
      this.rightSource = rightSource;
    },
    selectChange(sourceSelectedKeys, targetSelectedKeys) {
      this.selectedKeys = [...sourceSelectedKeys, ...targetSelectedKeys];
    },
    //供外部调用
    getSelectedData() {
      return cloneDeep(this.rightSource);
    },
    customRow(record) {
      return {
        on: {
          click: () => {
            if (this.disabled || record.disabled) {
              return;
            }
            let chosenIndex = null;
            let isSelected = this.selectedKeys.some((val, index) => {
              if (val === record.key) {
                chosenIndex = index;
                return true;
              } else {
                return false;
              }
            });
            if (isSelected) {
              this.selectedKeys.splice(chosenIndex, 1);
            } else {
              this.selectedKeys.push(record.key);
            }
          },
        },
      };
    },
  },
  render(h) {
    let {
      titles,
      disabled,
      listStyle,
      selectedKeys,
      targetKeys,
      tableColumn,
      leftTableColumn,
      rightTableColumn,
      leftFilter,
      rightFilter,
      customRow,

      totalDataSource,
      leftSource,
      rightSource,
      leftPagination,
      rightPagination,

      selectChange,
      handleBtnChange,

      localFilter,
    } = this;

    let _this = this;

    return (
      <div class="customTransferTable">
        <ATransfer
          {...{
            ref: 'transfer',
            props: {
              listStyle,
              disabled,
              titles,
              rowKey: record => record.key,
              dataSource: totalDataSource,
              selectedKeys,
              targetKeys,
            },
            scopedSlots: {
              children: slotData => {
                let {
                  props: { titleText, checkedKeys, disabled },
                  on: { itemSelect, itemSelectAll },
                } = slotData;
                let isLeft = titleText === titles[0];

                let _leftSource = localFilter(leftSource, leftFilter);

                let _rightSource = localFilter(rightSource, rightFilter);

                let rowSelection = {
                  getCheckboxProps(row) {
                    return {
                      props: {
                        disabled: disabled || row.disabled,
                      },
                    };
                  },
                  onSelect(row, checked) {
                    itemSelect(row.key, checked);
                  },
                  onSelectAll(checked, selectedRows, changeRows) {
                    itemSelectAll(changeRows.map(({ key }) => key), checked);
                  },
                  selectedRowKeys: isLeft ? [].concat(targetKeys).concat(checkedKeys) : checkedKeys,
                };

                let currentPagination = isLeft
                  ? {
                      ...leftPagination,
                      onChange(currPage) {
                        _this.leftPagination.current = currPage;
                      },
                    }
                  : {
                      ...rightPagination,
                      onChange(currPage) {
                        _this.rightPagination.current = currPage;
                      },
                    };

                let tableOption = {
                  props: {
                    rowKey: 'key',
                    tableColumns: (isLeft ? leftTableColumn : rightTableColumn) || tableColumn,
                    tableData: isLeft ? _leftSource : _rightSource,
                    maxHeight: 'none',
                    needPagination: false,
                    tableProp: {
                      rowSelection,
                      pagination: currentPagination,
                      customRow,
                    },
                  },
                  on: {
                    tableChange([pagination, filters, sorter]) {
                      _this.$emit('tableChange', {
                        isLeft,
                        pagination,
                        filters,
                        sorter,
                      });
                    },
                  },
                };

                return (
                  <div class="list-content-wrapper">
                    <div class="transfer-table-content">
                      {_this.$scopedSlots.table ? (
                        _this.$scopedSlots.table({
                          ...tableOption,
                          isLeft,
                        })
                      ) : (
                        <CTable
                          {...{
                            ...tableOption,
                            scopedSlots: _this.$scopedSlots,
                          }}
                        />
                      )}
                    </div>
                  </div>
                );
              },
            },
            on: {
              selectChange,
              change: handleBtnChange,
            },
          }}
        />
      </div>
    );
  },
};
